package com.nettest.service.system;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nettest.bean.BaseCriteriaVo;
import com.nettest.bean.system.StaffCriteriaVo;
import com.nettest.dao.system.StaffDao;
import com.nettest.entity.BaseEntity;
import com.nettest.entity.system.Role;
import com.nettest.entity.system.Staff;
import com.nettest.service.BaseIbatisService;
import com.nettest.util.StringUtils;

@Service
@Transactional
public class StaffService extends BaseIbatisService {
	@Autowired
	private StaffDao staffDao;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PasswordEncoder passwordEncoder;
	
	public List<Staff> queryByCriteria(BaseCriteriaVo criteriaVo) throws Exception {
		List<Staff> result = staffDao.queryStaffByCriteria(criteriaVo);
		return result;
	}

	public BaseEntity save(BaseEntity entity) throws Exception {
		return staffDao.save((Staff)entity);
	}

	public void delete(Long id) throws Exception {
		staffDao.delete(id);
	}

	public List<?> executeQuery(String sql) throws Exception {
		return staffDao.findBySql(sql);
	}

	public int totalSize(BaseCriteriaVo criteriaVo) throws Exception {
		return staffDao.totalSize(criteriaVo);
	}

	public Staff get(Serializable id) throws Exception {
		return staffDao.get(id);
	}
	
	protected Set<Criterion> getCriteriaSet(BaseCriteriaVo criteriaVo) {
		Set<Criterion> set = new HashSet<Criterion>();
		StaffCriteriaVo vo = (StaffCriteriaVo)criteriaVo;
		if(vo.getStaffNo() != null) {
			set.add(Restrictions.ilike("staffNo",vo.getStaffNo(),MatchMode.ANYWHERE));
		} 
		if(vo.getStaffName() != null) {
			set.add(Restrictions.ilike("staffName",vo.getStaffName(),MatchMode.ANYWHERE));
		}
		
		if(vo.getActive() != null) {
			set.add(Restrictions.eq("active",vo.getActive()));
		}
		return set;
	}

	public Staff getOneStaff(String staffNo) {
		List<Staff> list = staffDao.findBySql("select s from Staff s where s.staffNo=?", staffNo);
		if(!list.isEmpty()) {
			Staff staff = list.get(0);
			staff.getRoles().size();
			return staff;
		}
		return null;
	}

	public Staff loadStaff(String staffNo) {
		List<Staff> list = staffDao.findBySql("select s from Staff s where s.staffNo=?", staffNo);
		if(!list.isEmpty()) {
			Staff staff = list.get(0);
			Set<Role> roles = staff.getRoles();
			for (Role role : roles) {
				role.getMenus().size();
			}
			return staff;
		}
		return null;
	}

	public Staff insertStaff(Staff staff) throws Exception {
		String password = staff.getPassword() == null ? staff.getStaffNo() : staff.getPassword();
		Object salt = staff.getStaffNo();
        staff.setPassword(passwordEncoder.encodePassword(password,salt));
        String roleIds = staff.getRoleId();
        List<String> list = StringUtils.toList(roleIds, ";");
        Set<Role> roles = new HashSet<Role>();
        for (String roleId : list) {
        	Role role = roleService.get(roleId);
        	roles.add(role);
		}
        staff.setActive(true);
        staff.setRoles(roles);
        return (Staff) staffDao.save(staff);
	}

	public void updateStaff(Staff staff, Staff oldStaff) throws Exception{
		oldStaff.setStaffName(staff.getStaffName());
        oldStaff.setSex(staff.getSex());
        oldStaff.setEmployDate(staff.getEmployDate());
        oldStaff.setPosition(staff.getPosition());
        oldStaff.setTelephone(staff.getTelephone());
        oldStaff.setMobile(staff.getMobile());
        oldStaff.setQq(staff.getQq());
        oldStaff.setEmail(staff.getEmail());
        oldStaff.setAddress(staff.getAddress());
        oldStaff.setDeptId(staff.getDeptId());
        oldStaff.setMemo(staff.getMemo());
        
        String roleIds = staff.getRoleId();
        List<String> list = StringUtils.toList(roleIds, ";");
        Set<Role> roles = new HashSet<Role>();
        for (String roleId : list) {
        	Role role = roleService.get(roleId);
        	roles.add(role);
		}
        oldStaff.setRoles(roles);
        staffDao.save(oldStaff);
	}
	
	public List<String> getStaffNoByRoleId(String roleId, boolean includeChild) {
		List<String> staffNos = new ArrayList<String>();
		try {
			Role role = roleService.queryRoleById(roleId);
			Set<Staff> staffs = role.getStaffs();
			for (Staff staff : staffs) {
				staffNos.add(staff.getStaffNo());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return staffNos;
	}

	@SuppressWarnings("unchecked")
	public List<String> getStaffNoByDeptId(String deptId, boolean b) {
		List<String> result = null;
		String sql = "SELECT s.staffNo" +
				"           FROM Staff s" +
				"          WHERE s.deptId LIKE ?";
		try {
			if(b) {
				deptId = deptId + "%";
			}
			result = staffDao.getHibernateTemplate().find(sql, deptId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public List<Staff> getAllStaff() throws Exception {
		String sql = "select s from Staff s where s.active = true order by s.staffNo";
		return staffDao.findBySql(sql);
	}
	
	@SuppressWarnings("unchecked")
	public List<String> getRoleIdBelongStaff(String staffNo) {
		return (List<String> )queryForList("selectRoleIdBelongStaff", staffNo);
    }
	
	public StaffDao getStaffDao() {
		return staffDao;
	}

	public void setStaffDao(StaffDao staffDao) {
		this.staffDao = staffDao;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public PasswordEncoder getPasswordEncoder() {
		return passwordEncoder;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}
}
